

#include "E7ZoomLayer.h"

CE7ZoomLayer::CE7ZoomLayer()
{
//    autorelease() ;
    m_bIsReged = false ;

    setIsTouchEnabled(true) ;
    schedule(schedule_selector(CE7ZoomLayer::step)) ;
    m_fTargetScale = 0.0f ;
    m_bIsAction = false ;
}

CE7ZoomLayer::~CE7ZoomLayer()
{
    unscheduleAllSelectors() ;
}

void CE7ZoomLayer::RegCallBackFunc(TouchedCallBack singlefunc, TouchedCallBack doublefunc)
{
    m_bIsReged = true ;
    m_funcSingleTouched = singlefunc ;
    m_funcDoubleTouched = doublefunc ;
}

void CE7ZoomLayer::LoadRes(CCLayer* pGame, CCSize texturesize, CCLayer* pBack)
{
    m_sWinSize = CCDirector::sharedDirector()->getWinSize() ;

    if (NULL == pGame)
    {
        printf("CE7ZoomLayer::LoadRes NULL == pGame\n") ;
        return ;
    }
    m_pGameS = pGame ;
    m_pGameS->setPosition(getPosition()) ;
//    addChild(m_pGameS) ;

    m_sTextureSize = texturesize ;

//    m_pBackS = pBack ;
//    m_pBackS->setPosition(m_pGameS->getPosition()) ;

    printf("pos info: [%f][%f] [%f][%f]\n", getPosition().x, getPosition().y, m_pGameS->getPosition().x, m_pGameS->getPosition().y) ;
//    m_pGameS->setPosition(ccp(-512, -384)) ;
//    printf("zoomplayer position: [%f][%f]\n", getPosition().x, getPosition().y) ;
}

void CE7ZoomLayer::Reset()
{
    m_fTargetScale = ZOOM_SCALE_MIN ;
    m_bIsAction = true ;
}

void CE7ZoomLayer::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
{
    m_bIsTouch = true ;

    if (1 != pTouches->count())
    {
        printf("CE7ZoomLayer touch began function : [pTouches->count [%d]]\n", pTouches->count()) ;
        return ;
    }

    if (!m_bIsReged)
    {
        printf("CE7ZoomLayer touch began function : [m_bIsReged is false]\n") ;
        return ;
    }

    CCSetIterator iterTouch1 = pTouches->begin() ;
    CCTouch *touch =  (CCTouch*)(*iterTouch1) ;

    m_posS = convertTouchToNodeSpace(touch) ;
    gettimeofday(&m_tS, NULL) ;
}

void CE7ZoomLayer::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent)
{
//    printf("pTouches->count(): [%d]\n", pTouches->count()) ;
    if (1 == pTouches->count())//单点
    {
        CCSetIterator iterTouch1 = pTouches->begin() ;
        CCTouch *touch =  (CCTouch*)(*iterTouch1) ;

        CCPoint touchLocation = this->convertTouchToNodeSpace(touch) ;
        CCPoint oldTouchLocation = touch->previousLocationInView(touch->view()) ;
        oldTouchLocation = CCDirector::sharedDirector()->convertToGL(oldTouchLocation) ;
        oldTouchLocation = this->convertToNodeSpace(oldTouchLocation) ;
        CCPoint translation = ccpSub(touchLocation, oldTouchLocation) ;

        CCPoint newPos = ccpAdd(m_pGameS->getPosition(), translation) ;

        float offsety = (m_sTextureSize.height - m_sWinSize.height) * m_pGameS->getScale() ;
        float minx = m_sWinSize.width - m_sTextureSize.width * m_pGameS->getScale() ;
        float miny = m_sWinSize.height - m_sTextureSize.height * m_pGameS->getScale() + offsety ;
        float maxx = 0.0f ;
        float maxy = 0.0f + offsety ;
//        printf("debug info - 1: [%f][%f] ---[%f]-- [%f][%f]\n", minx, maxy, m_pGameS->getScale(), newPos.x, newPos.y) ;
        if (newPos.x < minx)
        {
            newPos.x = minx ;
        }
        else if (newPos.x > maxx)
        {
            newPos.x = maxx ;
        }
        if (newPos.y < miny)
        {
            newPos.y = miny ;
        }
        else if (newPos.y > maxy)
        {
            newPos.y = maxy ;
        }
        m_pGameS->setPosition(newPos) ;
//        m_pBackS->setPosition(newPos) ;
    }
    else if (pTouches->count() == 2)//2点
    {
        int i = 0 ;
        CCTouch *pCurTouch1 ;
        CCTouch *pCurTouch2 ;

        for (CCSetIterator iterTouch = pTouches->begin(); iterTouch != pTouches->end(); ++iterTouch)
        {
            if (i == 0)
            {
                pCurTouch1 =  (CCTouch*)(*iterTouch) ; //获得第一个触摸点
            }
            else if (i == 1)
            {
                pCurTouch2 =  (CCTouch*)(*iterTouch) ;
            }

            ++i ;
        }

        CCPoint ft = pCurTouch1->locationInView(pCurTouch1->view()) ;
        CCPoint st = pCurTouch2->locationInView(pCurTouch2->view()) ;
        m_fTouchEnd = sqrtf((ft.x - st.x)*(ft.x - st.x) + (ft.y - st.y)*(ft.y - st.y)) ;

        if (m_bIsTouch)
        {
            m_fTouchStart = m_fTouchEnd ;
            m_bIsTouch = false ;
        }

        float scale_set = 200.0f ;
        float temp_length = m_fTouchEnd-m_fTouchStart ;
        float newscale = m_pGameS->getScale() + temp_length/scale_set ;

        if (ZOOM_SCALE_MAX < newscale)
        {
            newscale = ZOOM_SCALE_MAX ;
        }
        else if (ZOOM_SCALE_MIN > newscale)
        {
            newscale = ZOOM_SCALE_MIN ;
        }
//        m_pGameS->setScale(newscale) ;

        CCPoint newPos = m_pGameS->getPosition() ;
        CCPoint offsetPos = CCPointZero ;
        CCPoint centerPos = ccp((st.x+ft.x)/2.0f, (st.y+ft.y)/2.0f) ;

        offsetPos = ccp(centerPos.x * (newscale-m_pGameS->getScale()), centerPos.y * (newscale-m_pGameS->getScale())) ;
//        offsetPos = ccp(0, 0) ;
        newPos = ccpSub(newPos, offsetPos) ;

        float offsety = (m_sTextureSize.height - m_sWinSize.height) * m_pGameS->getScale() ;
        float minx = m_sWinSize.width - m_sTextureSize.width * m_pGameS->getScale() ;
        float miny = m_sWinSize.height - m_sTextureSize.height * m_pGameS->getScale() + offsety ;
        float maxx = 0.0f ;
        float maxy = 0.0f + offsety ;
//        printf("debug info - 1: [%f][%f] ---[%f]-- [%f][%f]\n", minx, maxy, m_pGameS->getScale(), newPos.x, newPos.y) ;

        if (newPos.x < minx)
        {
            newPos.x = minx ;
        }
        else if (newPos.x > maxx)
        {
            newPos.x = maxx ;
        }
        if (newPos.y < miny)
        {
            newPos.y = miny ;
        }
        else if (newPos.y > maxy)
        {
            newPos.y = maxy ;
        }

        m_pGameS->setScale(newscale) ;
        m_pGameS->setPosition(newPos) ;

//        m_pBackS->setScale(newscale) ;
//        m_pBackS->setPosition(newPos) ;

        m_fTouchStart = m_fTouchEnd ;
    }
}

void CE7ZoomLayer::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent)
{
/*
 
 struct timeval s ;
 struct timeval e ;
 bool flag = false ;
 
    CCTouch* pTouch1 ;
    int count = 0 ;
    for (CCSetIterator iterTouch = pTouches->begin(); iterTouch != pTouches->end(); ++iterTouch)
    {
        pTouch1 =  (CCTouch*)(*iterTouch) ;
        ++count ;
    }

    printf("ccTouchesEnded count: [%d]\n", count) ;
    if (1 != count)
    {
        return ;
    }

    if (!flag)
    {
        gettimeofday(&s, NULL) ;
        flag = true ;
    }
    else
    {
        gettimeofday(&e, NULL) ;

        long interval = (e.tv_sec - s.tv_sec) * 1000000 + e.tv_usec-s.tv_usec ;
        if (500000 > interval)
        {
            // todo.
            printf("enter ==========\n") ;
            CCSize s = CCDirector::sharedDirector()->getWinSize() ;
            CCSprite *newSp =(CCSprite*)getChildByTag(123123) ;

            float newscale = newSp->getScale() ;
            if (newscale <= 1.0f)
            {
                newscale = 2.0f ;
            }
            else
            {
                newscale = 0.5f ;
            }
            newSp->setScale(newscale) ;

            CCPoint newPos = newSp->getPosition() ;
            int midx = newSp->getTexture()->getContentSize().width*newSp->getScale()/2 ;
            int midy = newSp->getTexture()->getContentSize().height*newSp->getScale()/2 ;
            if (s.width-midx > newPos.x)
            {
                newPos.x = s.width-midx ;
            }
            if (midx < newPos.x)
            {
                newPos.x = midx ;
            }
            if (s.height-midy > newPos.y)
            {
                newPos.y = s.height-midy ;
            }
            if (midy < newPos.y)
            {
                newPos.y = midy ;
            }
            newSp->setPosition(newPos) ;
        }

        printf("time: [%ld]\n", interval) ;
        flag = false ;
    }
*/
    if (1 != pTouches->count())
    {
        printf("CE7ZoomLayer touch end function : [pTouches->count [%d]]\n", pTouches->count()) ;
        return ;
    }

    if (!m_bIsReged)
    {
        printf("CE7ZoomLayer touch end function : [m_bIsReged is false]\n") ;
        return ;
    }

    // check distance.
    CCSetIterator iterTouch1 = pTouches->begin() ;
    CCTouch *touch =  (CCTouch*)(*iterTouch1) ;
    m_posE = convertTouchToNodeSpace(touch) ;
    float dist = sqrt((m_posE.x-m_posS.x)*(m_posE.x-m_posS.x) - (m_posE.y-m_posS.y)*(m_posE.y-m_posS.y)) ;
    if (10.0f * m_pGameS->getScale() < dist)
    {
        printf("CE7ZoomLayer touch end function : [CCPointEqualToPoint] [%f]\n", dist) ;
        return ;
    }
    // check interval.
    gettimeofday(&m_tE, NULL) ;
    int interval = (m_tE.tv_sec-m_tS.tv_sec)*1000000 + (m_tE.tv_usec-m_tS.tv_usec) ;
    if (0 > interval || 500000 < interval)
    {
        printf("CE7ZoomLayer touch end function : [time out [%d]]\n", interval) ;
        return ;
    }

    m_posE = ccpSub(m_posE, m_pGameS->getPosition()) ;
    m_posE = ccp(m_posE.x/m_pGameS->getScale(), m_posE.y/m_pGameS->getScale()) ;

    m_funcSingleTouched(ccp(m_pGameS->getPosition().x,
                            m_pGameS->getPosition().y),
                        m_pGameS->getScale(), m_posE) ;
}

void CE7ZoomLayer::ccTouchesCancelled(CCSet*pTouches, CCEvent *pEvent)
{
    printf("CE7ZoomController::ccTouchesCancelled(CCSet*pTouches, CCEvent *pEvent)\n");
}

void CE7ZoomLayer::menuCloseCallback(CCObject* pSender)
{
	CCDirector::sharedDirector()->end();

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
	exit(0);
#endif
}

void CE7ZoomLayer::step(ccTime dt)
{
    if (!m_bIsAction)
    {
        return ;
    }

    ScaleAction() ;
    
}

void CE7ZoomLayer::ScaleAction()
{
    printf("enter scale action\n") ;
    if (abs(m_fTargetScale - m_pGameS->getScale()) <= 0.1f)
    {
        m_bIsAction = false ;
        return ;
    }

    CCPoint newPos = m_pGameS->getPosition() ;

    CCPoint centerPos = m_pGameS->getPosition() ;
    
    CCPoint offsetPos = ccp(centerPos.x * (m_fTargetScale-m_pGameS->getScale()), centerPos.y * (m_fTargetScale-m_pGameS->getScale())) ;
    //        offsetPos = ccp(0, 0) ;
    newPos = ccpAdd(newPos, offsetPos) ;

    float offsety = (m_sTextureSize.height - m_sWinSize.height) * m_pGameS->getScale() ;
    float minx = m_sWinSize.width - m_sTextureSize.width * m_pGameS->getScale() ;
    float miny = m_sWinSize.height - m_sTextureSize.height * m_pGameS->getScale() + offsety ;
    float maxx = 0.0f ;
    float maxy = 0.0f + offsety ;
    
    if (newPos.x < minx)
    {
        newPos.x = minx ;
    }
    else if (newPos.x > maxx)
    {
        newPos.x = maxx ;
    }
    if (newPos.y < miny)
    {
        newPos.y = miny ;
    }
    else if (newPos.y > maxy)
    {
        newPos.y = maxy ;
    }
    
    if (m_fTargetScale > m_pGameS->getScale())
    {
        m_pGameS->setScale(m_pGameS->getScale()+0.1f) ;
    }
    else
    {
        m_pGameS->setScale(m_pGameS->getScale()-0.1f) ;
    }
    m_pGameS->setPosition(newPos) ;

//    m_pBackS->setScale(m_pGameS->getScale()) ;
//    m_pBackS->setPosition(m_pGameS->getPosition()) ;
}





















